package com.shirley.myserialportapp

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import com.shirley.myserialportapp.widget.ChooseBaudRateDialog
import com.shirley.serialportlib.SerialPortManager
import com.shirley.serialportlib.entity.Device
import com.shirley.serialportlib.listener.OnSerialPortOpenListener
import kotlinx.android.synthetic.main.activity_serial_port.*
import java.io.File

class SerialPortActivity : AppCompatActivity(), OnSerialPortOpenListener {

    private var mBaudPortDialog: ChooseBaudRateDialog? = null
    private var mSerialPortDevice: File? = null
    private var mBaudRate = -1
    private var mSerialPortManager: SerialPortManager? = null
    private var mSerialPortOpened = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_serial_port)

        val device: Device = intent.getSerializableExtra("device") as Device
        mSerialPortDevice = device.file
        tvSerialPortPath.text = String.format(getString(R.string.serial_port_path), mSerialPortDevice?.absolutePath)
        tvBaudRate.text = String.format(getString(R.string.baud_rate), getString(R.string.click_to_set_baud_rate))

        mSerialPortManager = SerialPortManager()
    }

    fun chooseBaudRate(view: View) {
        if (mBaudPortDialog == null) {
            mBaudPortDialog = ChooseBaudRateDialog(this)
            mBaudPortDialog?.setOnChooseBaudRateListener(object : ChooseBaudRateDialog.OnChooseBaudRateListener {
                override fun onChooseBaudRate(baudRate: Int?) {
                    baudRate?.let {
                        mBaudRate = baudRate
                        tvBaudRate.text = String.format(getString(R.string.baud_rate), it.toString())
                    }
                }
            })
        }
        mBaudPortDialog?.show()
    }

    fun openSerialPort(view: View) {
        mSerialPortDevice?.let {
            if (mBaudRate == -1) {
                Toast.makeText(this, getString(R.string.set_baud_rate_first), Toast.LENGTH_SHORT).show()
            } else {
                // 每次关闭串口时监听事件会被置为null
                mSerialPortManager?.setSerialPortOpenListener(this)
                mSerialPortManager?.openSerialPort(mSerialPortDevice, mBaudRate)
            }
        }
    }

    override fun onSuccess(device: File?) {
        mSerialPortOpened = true
        tvLog.append(String.format(getString(R.string.open_serial_port_success), device?.absolutePath))
        tvLog.append("\n")
        tvBaudRate.isClickable = false
        tvOpen.isEnabled = false
        tvSend.isEnabled = true
        tvClose.isEnabled = true
    }

    override fun onFail(device: File?, status: OnSerialPortOpenListener.Status?) {
        when (status) {
            OnSerialPortOpenListener.Status.WITHOUT_READ_WRITE_PERMISSION -> {
                showAlertDialog(device?.absolutePath, getString(R.string.without_read_write_permission))
            }
            OnSerialPortOpenListener.Status.OPEN_FAIL -> {
                showAlertDialog(device?.absolutePath, getString(R.string.open_serial_port_failed))
            }
        }
    }

    /**
     * 展示警示弹框
     */
    private fun showAlertDialog(title: String?, message: String) {
        AlertDialog.Builder(this)
            .setTitle(title)
            .setMessage(message)
            .setPositiveButton("Exit") { dialog, _ ->
                run {
                    dialog.dismiss()
                    finish()
                }
            }
            .setCancelable(false)
            .create()
            .show()
    }

    override fun onDestroy() {
        super.onDestroy()
        mSerialPortManager?.let {
            if (mSerialPortOpened) {
                mSerialPortManager?.closeSerialPort()
            }
            mSerialPortManager = null
        }
    }

    fun closeSerialPort(view: View) {
        if (mSerialPortOpened) {
            mSerialPortManager?.closeSerialPort()
            tvLog.append(String.format(getString(R.string.close_serial_port), mSerialPortDevice?.absolutePath))
            tvLog.append("\n")
            tvBaudRate.isClickable = true
            tvOpen.isEnabled = true
            tvOpen.isClickable = true
            tvSend.isEnabled = false
            tvClose.isEnabled = false
        }
    }
}
